package com.cyan.note.service.manager.impl;

import com.cyan.note.common.ApiResult;
import com.cyan.note.common.ResultCode;
import com.cyan.note.dto.manager.config.OrderTypeConfigDTO;
import com.cyan.note.dto.manager.config.OrderSourceConfigDTO;
import com.cyan.note.entity.ShopSetting;
import com.cyan.note.mapper.ShopSettingMapper;
import com.cyan.note.service.manager.ManagerSettingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 店长端-设置配置服务实现类
 * 
 * @author ZhangzhenYu
 * @since 2025-01-15
 */
@Service
@Slf4j
public class ManagerSettingServiceImpl implements ManagerSettingService {

    @Autowired
    private ShopSettingMapper shopSettingMapper;

    @Override
    public ApiResult<Map<String, String>> getAllSettings(Long shopId) {
        try {
            Map<String, String> settings = shopSettingMapper.selectAllSettingsAsMap(shopId);
            return ApiResult.success(settings != null ? settings : new HashMap<>());
        } catch (Exception e) {
            log.error("获取店铺所有设置失败", e);
            return ApiResult.error(ResultCode.ERROR, "获取店铺设置失败");
        }
    }

    @Override
    public ApiResult<List<ShopSetting>> getSettingsByCategory(Long shopId, String category) {
        try {
            List<ShopSetting> settings = shopSettingMapper.selectByShopAndCategory(shopId, category);
            return ApiResult.success(settings != null ? settings : new ArrayList<>());
        } catch (Exception e) {
            log.error("获取分类设置失败", e);
            return ApiResult.error(ResultCode.ERROR, "获取分类设置失败");
        }
    }

    @Override
    public ApiResult<String> getSettingValue(Long shopId, String settingKey) {
        try {
            String value = shopSettingMapper.selectSettingValue(shopId, settingKey);
            return ApiResult.success(value);
        } catch (Exception e) {
            log.error("获取设置值失败", e);
            return ApiResult.error(ResultCode.ERROR, "获取设置值失败");
        }
    }

    @Override
    @Transactional
    public ApiResult<Void> updateSetting(Long shopId, String settingKey, String settingValue, Long operatorId) {
        try {
            // 查找现有设置
            ShopSetting setting = shopSettingMapper.selectByShopAndKey(shopId, settingKey);
            
            if (setting != null) {
                // 更新现有设置
                setting.setSettingValue(settingValue);
                setting.setUpdatedBy(operatorId);
                setting.setUpdatedAt(LocalDateTime.now());
                shopSettingMapper.updateById(setting);
            } else {
                // 创建新设置
                setting = new ShopSetting();
                setting.setShopId(shopId);
                setting.setSettingKey(settingKey);
                setting.setSettingValue(settingValue);
                setting.setSettingType(ShopSetting.SettingType.STRING);
                setting.setSettingCategory(inferCategoryFromKey(settingKey));
                setting.setIsSystem(false);
                setting.setCreatedBy(operatorId);
                setting.setUpdatedBy(operatorId);
                setting.setCreatedAt(LocalDateTime.now());
                setting.setUpdatedAt(LocalDateTime.now());
                shopSettingMapper.insert(setting);
            }
            
            return ApiResult.success();
        } catch (Exception e) {
            log.error("更新设置失败", e);
            return ApiResult.error(ResultCode.ERROR, "更新设置失败");
        }
    }

    @Override
    @Transactional
    public ApiResult<Void> batchUpdateSettings(Long shopId, List<ShopSetting> settings, Long operatorId) {
        try {
            for (ShopSetting setting : settings) {
                setting.setShopId(shopId);
                setting.setUpdatedBy(operatorId);
                setting.setUpdatedAt(LocalDateTime.now());
            }
            
            int result = shopSettingMapper.batchUpsertSettings(shopId, settings);
            if (result > 0) {
                return ApiResult.success();
            } else {
                return ApiResult.error(ResultCode.OPERATION_FAILED, "批量更新设置失败");
            }
        } catch (Exception e) {
            log.error("批量更新设置失败", e);
            return ApiResult.error(ResultCode.ERROR, "批量更新设置失败");
        }
    }

    @Override
    @Transactional
    public ApiResult<Void> resetCategorySettings(Long shopId, String category, Long operatorId) {
        try {
            // 删除该分类的所有设置
            shopSettingMapper.deleteByShopAndCategory(shopId, category);
            
            // 重新创建默认设置
            List<ShopSetting> defaultSettings = getDefaultSettingsByCategory(shopId, category, operatorId);
            if (!defaultSettings.isEmpty()) {
                shopSettingMapper.batchUpsertSettings(shopId, defaultSettings);
            }
            
            return ApiResult.success();
        } catch (Exception e) {
            log.error("重置分类设置失败", e);
            return ApiResult.error(ResultCode.ERROR, "重置分类设置失败");
        }
    }

    @Override
    public ApiResult<List<OrderTypeConfigDTO>> getOrderTypeConfig(Long shopId) {
        try {
            List<OrderTypeConfigDTO> configs = new ArrayList<>();
            
            // 陪玩单配置
            OrderTypeConfigDTO hourlyConfig = new OrderTypeConfigDTO();
            hourlyConfig.setOrderType("hourly");
            hourlyConfig.setOrderTypeName("陪玩单");
            hourlyConfig.setEnabled(true);
            hourlyConfig.setMinDuration(Integer.parseInt(getSettingValueOrDefault(shopId, ShopSetting.SettingKey.MIN_DURATION_HOURS, "1")));
            hourlyConfig.setMaxDuration(Integer.parseInt(getSettingValueOrDefault(shopId, ShopSetting.SettingKey.MAX_DURATION_HOURS, "8")));
            hourlyConfig.setDefaultCommissionRate(Double.parseDouble(getSettingValueOrDefault(shopId, ShopSetting.SettingKey.DEFAULT_COMMISSION_RATE, "30")));
            configs.add(hourlyConfig);
            
            // 护航单配置
            OrderTypeConfigDTO fixedConfig = new OrderTypeConfigDTO();
            fixedConfig.setOrderType("fixed");
            fixedConfig.setOrderTypeName("护航单");
            fixedConfig.setEnabled(true);
            fixedConfig.setMinDuration(1);
            fixedConfig.setMaxDuration(24);
            fixedConfig.setDefaultCommissionRate(Double.parseDouble(getSettingValueOrDefault(shopId, ShopSetting.SettingKey.DEFAULT_COMMISSION_RATE, "30")));
            configs.add(fixedConfig);
            
            return ApiResult.success(configs);
        } catch (Exception e) {
            log.error("获取订单类型配置失败", e);
            return ApiResult.error(ResultCode.ERROR, "获取订单类型配置失败");
        }
    }

    @Override
    @Transactional
    public ApiResult<Void> updateOrderTypeConfig(Long shopId, List<OrderTypeConfigDTO> configs, Long operatorId) {
        try {
            for (OrderTypeConfigDTO config : configs) {
                updateSetting(shopId, ShopSetting.SettingKey.MIN_DURATION_HOURS, String.valueOf(config.getMinDuration()), operatorId);
                updateSetting(shopId, ShopSetting.SettingKey.MAX_DURATION_HOURS, String.valueOf(config.getMaxDuration()), operatorId);
                updateSetting(shopId, ShopSetting.SettingKey.DEFAULT_COMMISSION_RATE, String.valueOf(config.getDefaultCommissionRate()), operatorId);
            }
            return ApiResult.success();
        } catch (Exception e) {
            log.error("更新订单类型配置失败", e);
            return ApiResult.error(ResultCode.ERROR, "更新订单类型配置失败");
        }
    }

    @Override
    public ApiResult<List<OrderSourceConfigDTO>> getOrderSourceConfig(Long shopId) {
        try {
            List<OrderSourceConfigDTO> configs = new ArrayList<>();
            
            // 手动下单
            OrderSourceConfigDTO manualConfig = new OrderSourceConfigDTO();
            manualConfig.setOrderSource("manual");
            manualConfig.setOrderSourceName("手动下单");
            manualConfig.setEnabled(true);
            manualConfig.setDisplayOrder(1);
            configs.add(manualConfig);
            
            // 微信小程序
            OrderSourceConfigDTO wechatConfig = new OrderSourceConfigDTO();
            wechatConfig.setOrderSource("wechat_miniprogram");
            wechatConfig.setOrderSourceName("微信小程序");
            wechatConfig.setEnabled(true);
            wechatConfig.setDisplayOrder(2);
            configs.add(wechatConfig);
            
            // H5网站
            OrderSourceConfigDTO h5Config = new OrderSourceConfigDTO();
            h5Config.setOrderSource("h5_website");
            h5Config.setOrderSourceName("H5网站");
            h5Config.setEnabled(true);
            h5Config.setDisplayOrder(3);
            configs.add(h5Config);
            
            return ApiResult.success(configs);
        } catch (Exception e) {
            log.error("获取订单来源配置失败", e);
            return ApiResult.error(ResultCode.ERROR, "获取订单来源配置失败");
        }
    }

    @Override
    @Transactional
    public ApiResult<Void> updateOrderSourceConfig(Long shopId, List<OrderSourceConfigDTO> configs, Long operatorId) {
        try {
            // 这里可以根据需要保存订单来源的启用状态和排序
            return ApiResult.success();
        } catch (Exception e) {
            log.error("更新订单来源配置失败", e);
            return ApiResult.error(ResultCode.ERROR, "更新订单来源配置失败");
        }
    }

    @Override
    public ApiResult<Map<String, Object>> getSystemSettings(Long shopId) {
        try {
            Map<String, Object> settings = new HashMap<>();
            
            settings.put("timeoutReminderMinutes", Integer.parseInt(getSettingValueOrDefault(shopId, ShopSetting.SettingKey.TIMEOUT_REMINDER_MINUTES, "30")));
            settings.put("autoCancelMinutes", Integer.parseInt(getSettingValueOrDefault(shopId, ShopSetting.SettingKey.AUTO_CANCEL_MINUTES, "60")));
            settings.put("maxConcurrentOrders", Integer.parseInt(getSettingValueOrDefault(shopId, ShopSetting.SettingKey.MAX_CONCURRENT_ORDERS, "3")));
            settings.put("levelUpgradeAmount", Double.parseDouble(getSettingValueOrDefault(shopId, ShopSetting.SettingKey.LEVEL_UPGRADE_AMOUNT, "1000")));
            
            return ApiResult.success(settings);
        } catch (Exception e) {
            log.error("获取系统参数设置失败", e);
            return ApiResult.error(ResultCode.ERROR, "获取系统参数设置失败");
        }
    }

    @Override
    @Transactional
    public ApiResult<Void> updateSystemSettings(Long shopId, Map<String, Object> settings, Long operatorId) {
        try {
            for (Map.Entry<String, Object> entry : settings.entrySet()) {
                String key = entry.getKey();
                String value = String.valueOf(entry.getValue());
                updateSetting(shopId, key, value, operatorId);
            }
            return ApiResult.success();
        } catch (Exception e) {
            log.error("更新系统参数设置失败", e);
            return ApiResult.error(ResultCode.ERROR, "更新系统参数设置失败");
        }
    }

    /**
     * 获取设置值或默认值
     */
    private String getSettingValueOrDefault(Long shopId, String settingKey, String defaultValue) {
        try {
            String value = shopSettingMapper.selectSettingValue(shopId, settingKey);
            return value != null ? value : defaultValue;
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * 根据设置键推断分类
     */
    private String inferCategoryFromKey(String settingKey) {
        if (settingKey.contains("timeout") || settingKey.contains("cancel") || settingKey.contains("duration")) {
            return ShopSetting.SettingCategory.ORDER;
        } else if (settingKey.contains("commission") || settingKey.contains("rate")) {
            return ShopSetting.SettingCategory.FINANCE;
        } else if (settingKey.contains("level") || settingKey.contains("upgrade")) {
            return ShopSetting.SettingCategory.CUSTOMER;
        } else if (settingKey.contains("concurrent") || settingKey.contains("max")) {
            return ShopSetting.SettingCategory.WORKER;
        } else {
            return ShopSetting.SettingCategory.SYSTEM;
        }
    }

    /**
     * 获取分类的默认设置
     */
    private List<ShopSetting> getDefaultSettingsByCategory(Long shopId, String category, Long operatorId) {
        List<ShopSetting> defaultSettings = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();
        
        switch (category) {
            case ShopSetting.SettingCategory.ORDER:
                // 订单相关默认设置
                defaultSettings.add(createDefaultSetting(shopId, ShopSetting.SettingKey.TIMEOUT_REMINDER_MINUTES, "30", category, operatorId, now));
                defaultSettings.add(createDefaultSetting(shopId, ShopSetting.SettingKey.AUTO_CANCEL_MINUTES, "60", category, operatorId, now));
                defaultSettings.add(createDefaultSetting(shopId, ShopSetting.SettingKey.MIN_DURATION_HOURS, "1", category, operatorId, now));
                defaultSettings.add(createDefaultSetting(shopId, ShopSetting.SettingKey.MAX_DURATION_HOURS, "8", category, operatorId, now));
                break;
            case ShopSetting.SettingCategory.FINANCE:
                // 财务相关默认设置
                defaultSettings.add(createDefaultSetting(shopId, ShopSetting.SettingKey.DEFAULT_COMMISSION_RATE, "30", category, operatorId, now));
                break;
            case ShopSetting.SettingCategory.CUSTOMER:
                // 客户相关默认设置
                defaultSettings.add(createDefaultSetting(shopId, ShopSetting.SettingKey.LEVEL_UPGRADE_AMOUNT, "1000", category, operatorId, now));
                break;
            case ShopSetting.SettingCategory.WORKER:
                // 打手相关默认设置
                defaultSettings.add(createDefaultSetting(shopId, ShopSetting.SettingKey.MAX_CONCURRENT_ORDERS, "3", category, operatorId, now));
                break;
        }
        
        return defaultSettings;
    }

    /**
     * 创建默认设置
     */
    private ShopSetting createDefaultSetting(Long shopId, String key, String value, String category, Long operatorId, LocalDateTime now) {
        ShopSetting setting = new ShopSetting();
        setting.setShopId(shopId);
        setting.setSettingCategory(category);
        setting.setSettingKey(key);
        setting.setSettingValue(value);
        setting.setSettingType(ShopSetting.SettingType.STRING);
        setting.setDescription("默认设置");
        setting.setIsSystem(false);
        setting.setCreatedBy(operatorId);
        setting.setUpdatedBy(operatorId);
        setting.setCreatedAt(now);
        setting.setUpdatedAt(now);
        return setting;
    }
}